package com.itheima.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.entity.PageResult;
import com.itheima.entity.QueryPageBean;
import com.itheima.mapper.MenuMapper;
import com.itheima.mapper.UserMapper;
import com.itheima.pojo.Menu;
import com.itheima.pojo.User;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service(interfaceClass = UserService.class)
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MenuMapper menuMapper;

    /**
     * 通过用户名查询用户
     *
     * @param username
     * @return
     */
    @Override
    public User findByUsername(String username) {
        return userMapper.findByUsername(username);
    }

    /**
     * 添加用户数据
     * 在中间表添加
     * 对用户密码进行加密处理
     *
     * @param roleIds
     * @param user
     */
    @Override
    public void add(Integer[] roleIds, User user) {
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String newPassword = bCryptPasswordEncoder.encode(user.getPassword());
        user.setPassword(newPassword);
        userMapper.add(user);
        userMapper.setUserAndRole(user.getId(), roleIds);
    }

    /**
     * 根据ID查询获取分页信息
     *
     * @param queryPageBean
     * @return
     */
    @Override
    public PageResult findPage(QueryPageBean queryPageBean) {
        //使用mybatis的分页插件,查询语句会自动拦截，所以顺序不会变
        PageHelper.startPage(queryPageBean.getCurrentPage(), queryPageBean.getPageSize());
        List<User> roleList = userMapper.findByCondition(queryPageBean.getQueryString());
        PageInfo<User> pageInfo = new PageInfo<>(roleList);

        return new PageResult(pageInfo.getTotal(), pageInfo.getList());
    }

    /**
     * 回显用户信息
     *
     * @param id
     * @return
     */
    @Override
    public User findById(Integer id) {
        return userMapper.findById(id);
    }

    /**
     * 从中间表获取用户的角色数据
     *
     * @param id
     * @return
     */
    @Override
    public List<Integer> findRoleIdsByRoleId(Integer id) {
        return userMapper.findRoleIdsByRoleId(id);
    }

    /**
     * 编辑用户，顺便改一下中间表
     *
     * @param roleIds
     * @param user
     */
    @Override
    public void edit(Integer[] roleIds, User user) {
        userMapper.updateByUser(user);
        userMapper.clearByUserId(user.getId());
        userMapper.setUserAndRole(user.getId(),roleIds);
    }

    /**
     * 删除该用户，删除该用户中间表
     *
     * @param id
     */
    @Override
    public void deleteById(Integer id) {
        userMapper.clearByUserId(id);
        userMapper.deleteUserById(id);
    }

    /**
     * 根据用户名获取菜单
     *
     * @param userName
     * @return
     */
    @Override
    public List getMenuList(String userName) {
        List<Menu> menuList1 = menuMapper.getMenuListFor1(userName);
        List<Menu> menuList2 = menuMapper.getMenuListFor2(userName);
        List<Map> menuList = new ArrayList<>();

        //遍历循环父类菜单
        for (Menu menu1 : menuList1) {
            Map<String, Object> mapFor1 = new HashMap<>(4);
            mapFor1.put("path", menu1.getPath());
            mapFor1.put("title", menu1.getName());
            mapFor1.put("icon", menu1.getIcon());

            //为父类菜单新建一个临时的子类集合(map类型)，用来封装子类map
            List<Map> list1 = new ArrayList<>();
            mapFor1.put("children", list1);
            //循环遍历子类菜单，寻找子类的ParentMenuId与父类Id相同的菜单，并封装成map放入父类的临时子类集合
            for (Menu menu2 : menuList2) {
                if (menu2.getParentMenuId().equals(menu1.getId())) {
                    Map<String, Object> mapFor2 = new HashMap<>(4);
                    mapFor2.put("path", menu2.getPath());
                    mapFor2.put("title", menu2.getName());
                    mapFor2.put("linkUrl", menu2.getLinkUrl());
                    mapFor2.put("children", menu2.getChildren());
                    list1.add(mapFor2);
                }
            }

            //每循环一次，封装一个父类
            menuList.add(mapFor1);
        }
        return menuList;
    }

}
